#include <iostream>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <atomic>
#include <thread>
#include <queue>
#include <mutex>
#include <condition_variable>
#include "A010.h"
#include <csignal>

#define watchdog_timeout 10

#define UART_CHOSE A010_UART_CHOSE

// 串口相关全局变量
int fd = -1;
std::atomic<bool> stopFlag{false};
bool RxThreadRunFlag = false;

int ConfigureSerial(int fd, speed_t speed) {
    close(fd);
    fd = open(UART_CHOSE, O_RDWR | O_NOCTTY);
    if (fd < 0) {
        perror("Open serial port failed");
        close(fd);
        return 1;
    }

    termios tty{};
    if (tcgetattr(fd, &tty) != 0) {
        perror("tcgetattr failed");
        return 1;
    }
    
    tty.c_cflag &= ~PARENB;
    tty.c_cflag &= ~CSTOPB;
    tty.c_cflag &= ~CSIZE;
    tty.c_cflag |= CS8;
    tty.c_cflag |= (CREAD | CLOCAL);
    tty.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
    // 修改输入模式设置
    tty.c_iflag &= ~(IXON | IXOFF | IXANY | ICRNL | IGNCR);  // 新增禁用回车转换
    tty.c_oflag &= ~(OPOST | ONLCR);  // 新增禁用输出转换
    
    if(cfsetispeed(&tty, speed))
    {
        printf("cfsetispeed failed\n");
        return 2;
    }

    if(cfsetospeed(&tty, speed))
    {
        printf("cfsetospeed failed\n");
        return 3;
    }
    
    tty.c_cc[VMIN] = 1;  // 1字节返回
    tty.c_cc[VTIME] = 1; // 100ms超时
    
    if (tcsetattr(fd, TCSANOW, &tty) != 0) {
        printf("tcsetattr failed\n");
    }

    // 设置为非阻塞模式
    fcntl(fd, F_SETFL, O_NONBLOCK);
    tcflush(fd, TCIOFLUSH);

    return 0;
}

// 在全局变量区域添加
std::atomic<int> watchdogCounter{0};

// 新增看门狗线程函数
void WatchdogThreadFunc() {
    const int TIMEOUT = watchdog_timeout; // 30秒超时
    watchdogCounter.store(watchdog_timeout);
    while (!stopFlag) {
        if (watchdogCounter.fetch_sub(1) <= 0) {
            std::cerr << "Watchdog timeout! " << std::endl;
            stopFlag = true;
            kill(getpid(), SIGINT);
            return;
        }
        sleep(1);
    }
}

// 修改队列结构定义（约50行）
struct {
    std::mutex mtx;
    std::condition_variable cv;
    std::queue<std::vector<uint8_t>> queue;
    const size_t MAX_QUEUE_SIZE = UART_RX_MAX_QUEUE_SIZE;    // 改为更大的队列容量
    const size_t MAX_BUFFER_SIZE = UART_RX_MAX_BUFFER_SIZE; 
    size_t totalBytes = 0;  // 新增总字节计数器
} rxData;

// 修改接收线程部分（约63行）
void RxThreadFunc() {
    uint8_t buf[rxData.MAX_BUFFER_SIZE]; // 读取缓冲区大小保持32KB（32768字节）
    std::cout << "start RxThreadFunc\n";
    RxThreadRunFlag = true;
    while (!stopFlag) {        
        ssize_t n = read(fd, buf, rxData.MAX_BUFFER_SIZE);
        if (n > 0) {            
            watchdogCounter.store(watchdog_timeout);
            std::vector<uint8_t> data;
            data.reserve(std::min(static_cast<size_t>(n), rxData.MAX_BUFFER_SIZE));
            
            // 将数据存入vector
            {
                std::unique_lock<std::mutex> lock(rxData.mtx);

                // 新增：计算总字节数
                const size_t newBytes = data.size() + n;
                
                // 修改判断条件：总字节数超过限制时清空
                if(rxData.totalBytes + newBytes > rxData.MAX_BUFFER_SIZE) {
                    std::queue<std::vector<uint8_t>> empty;
                    std::swap(rxData.queue, empty);
                    rxData.totalBytes = 0;  // 重置计数器
                    std::cout << "UART RX Reset" << std::endl;
                }
                
                data.insert(data.end(), buf, buf + n);
                rxData.queue.push(std::move(data));
                rxData.totalBytes += newBytes;  // 更新总字节数
                rxData.cv.notify_one();
            }
        }
        usleep(1000);
    }
}

void A010_Open(int uart)
{
    std::string res = UART_CHOSE;
    while(!RxThreadRunFlag)
    {
        usleep(1000);
    }

    if(res.find("USB") == std::string::npos)
    {
        std::cout << "A010 Open UART" << std::endl;
        usleep(50000);
        A010_Send(uart, A010_CONFIG_DISP_UART);
    }
    else
    {
        std::cout << "A010 Open USB" << std::endl;
        usleep(500000);
        A010_Send(uart, A010_CONFIG_DISP_USB); 
    }
}


void A010_DataProcessThread() {
    std::cout << "start DataProcessThread\n";
    A010_Open(fd);
    while (!stopFlag) {
        std::unique_lock<std::mutex> lock(rxData.mtx);
        // 修改为条件变量直接等待（而不是定时等待）
        rxData.cv.wait(lock, [&]{ return !rxData.queue.empty() || stopFlag; });
        
        // 批量处理数据
        while (!rxData.queue.empty()) {
            std::vector<uint8_t> data = std::move(rxData.queue.front()); // 使用移动语义
            const size_t dataSize = data.size(); // 先记录数据大小
            rxData.queue.pop();
            rxData.totalBytes -= dataSize; // 立即更新总字节数

            lock.unlock();  // 释放锁后再处理数据            
            
            // // 优化输出：仅显示前10字节示例
            // std::cout << "Recv " << dataSize << "B [";
            // for(size_t i=0; i<std::min(dataSize, size_t(10)); ++i) {
            //     printf("%02X ", data[i]);
            // }
            // if(dataSize > 10) std::cout << "...";
            // std::cout << "]\n";

            // 解析数据
            A010_ParseData(data.data(), dataSize);
            
            lock.lock();
        }
    }
}
int main()
{
    std::cout << "Open" << UART_CHOSE << "\n";
    // 打开串口
    fd = open(UART_CHOSE, O_RDWR | O_NOCTTY);
    if (fd < 0) {
        perror("Open serial port failed");
        close(fd);
        return 1;
    }

    if(ConfigureSerial(fd,B115200))
    {
        std::cout << "Configure serial port fail\n";
        close(fd);
        return 1;
    }

    if(A010_Init(fd))
    {
        std::cout << "A010 Init failed, Close serial port\n";
        close(fd);
        return 1;
    }

    // 启动接收线程和数据处理线程
    std::thread rxThread(RxThreadFunc);    
    std::thread processThread(A010_DataProcessThread);
    std::thread watchdogThread(WatchdogThreadFunc);

    rxThread.join();
    processThread.join();
    watchdogThread.join();
    
    std::cout << "stop thread\n";
    close(fd);

    return 0;
}
